//
//  OPSearch.m
//  OPFramework
//
//  Created by malcom on 7/29/08.
//  Copyright 2008 malcom-mac software. All rights reserved.
//

#import "OPSearch.h"


@implementation OPSearch

@synthesize p_results;

- (id) initToSearchKeywords:(NSString *) _keywords inBoard:(OPBoard *) _board {
	self = [super initWithBoard: _board];
	if (self != nil) {
		p_forumsToSearch = [[NSArray array] retain];
		p_searchWhere = [OPSearch_Where_All retain];
		p_orderResultBy = [OPSearch_OrderRes_Time retain];
		p_orderDescending = YES;
		p_resultsToShow = 300;
		p_limitDays = 30;
		p_whatResult = [OPSearch_WhatResult_Topics retain];
		p_searchInsideTopicID = [[NSNumber numberWithInt: 0] retain];
		p_keywords = [_keywords retain];
		
		p_results = [[OPPageContainer alloc] init];
	}
	return self;
}


- (id) initToSearch:(NSString *) _whatSearch keywords:(NSString *) _keys inBoard:(OPBoard *) _board specificTopicID:(NSNumber *) _topicID limitToForums:(NSArray *) _forums searchWhere:(NSString *) _where 
					orderBy:(NSString *) _order desc:(BOOL) _desc howShow:(int) _itemsToShow limitByDays:(int) _daylimit {
	self = [super init];
	if (self != nil) {
		p_forumsToSearch = (_forums == nil ? [[NSArray array] retain] : [_forums retain]);
		p_searchWhere = [_where retain];
		p_orderResultBy = [_order retain];
		p_orderDescending = _desc;
		p_resultsToShow = _itemsToShow;
		p_limitDays = _daylimit;
		p_whatResult = [_whatSearch retain];
		p_searchInsideTopicID = (_topicID == nil ? [[NSNumber numberWithInt: 0] retain] : [_topicID retain]);
		p_keywords = [_keys retain];
		
		p_results = [[OPPageContainer alloc] init];
		
		_delegateBoard = [_board retain];
	}
	return self;
}

- (void) dealloc {
	[p_forumsToSearch release];
	[p_searchWhere release];
	[p_orderResultBy release];
	[p_whatResult release];
	[p_searchInsideTopicID release];
	[p_keywords release];
	[p_results release];
	[super dealloc];
}


- (NSArray *) getResultsPage:(NSNumber *) _pgIdx {
	if ([_pgIdx intValue] == -1) return nil;
	
	// if we want to get a new copy or we have not yet downloaded the page or the cache is expired
	if ([p_results getPageAtIndex: _pgIdx] == nil || [self isCacheExpired]) {
		[self sendXMLRequestForMethod: @"msgs.searchInsideBoard" 
						   withParams: [NSArray arrayWithObjects:
												   p_whatResult,
												   _pgIdx,
													(p_whatResult == OPSearch_WhatResult_Topics ? [_delegateBoard.obj_boardConfig getPropertyForKey:OPBoardConfig_TopicsPerPage] 
																								: [_delegateBoard.obj_boardConfig getPropertyForKey:OPBoardConfig_PostsPerPage]),
													p_searchInsideTopicID,
													p_forumsToSearch,
													p_keywords,
													@"",
													[NSNumber numberWithBool: NO],
													p_searchWhere,
													[NSNumber numberWithBool: YES],
													p_orderResultBy,
													(p_orderDescending ? @"d" : @"a"),
													[NSNumber numberWithInt: p_resultsToShow],
													[NSNumber numberWithInt: p_limitDays],nil]
						parseSelector: @selector(_parseSearchResultsItems:)];
	}
	return [p_results getPageAtIndex: _pgIdx];
}

// async response
- (void)connection: (XMLRPCConnection *)connection didReceiveResponse:(XMLRPCResponse *)response forMethod: (NSString *)method {
	// super class check if it's an error, a numeric response or simply some data to parse
	if (![self _checkErrorInRawResponseFromServer: response forMethod:method]) {
		// data update to parse
		[self _parseSearchResultsItems: [NSArray arrayWithObjects: [response responseObject],method,nil]];
		// we can propagate the result to listeners
		[self dataUpdatedFor: self atMethod:method];	
	}
}

- (BOOL) _isNumericResponseFromServerAnErrorCode:(NSNumber *) _code forMethod:(NSString *) method {
	switch ([_code intValue]) {
		case OFAPI_SEARCH_NOT_ALLOWED:
		case OFAPI_SEARCH_NOT_CURRENTLY_AVAILABLE:
		case OFAPI_SEARCH_DISABLED_FLOODED:
		case OFAPI_SEARCH_AUTHORFIELD_TOOSHORT:
		case OFAPI_SEARCH_AUTHORFIELD_NOTVALIDNAMES:
		case OFAPI_SEARCH_NO_SEARCHMODULE:
		case OFAPI_SEARCH_GENERAL_ERROR:
		case OFAPI_SEARCH_NO_KEYWORDS_TOSEARCH:
		case OFAPI_SEARCH_NO_RESULTS:
			return YES;
	}
	return NO;
}

- (void) _parseSearchResultsItems:(NSArray *) _result {
	NSDictionary *resultsDict = [[_result objectAtIndex: 0] retain];
	
	p_results.p_totalPages = [[resultsDict objectForKey: @"total_pages"] intValue];
	p_results.p_totalElements = [[resultsDict objectForKey: @"total_items"] intValue];
	
	NSNumber *cPageIdx = [resultsDict objectForKey: @"current_page"];

	NSMutableArray *cPage = [[NSMutableArray alloc] init];

	if (p_whatResult == OPSearch_WhatResult_Topics) {
		for (NSDictionary *cTopicDic in [resultsDict objectForKey:@"results"]) {
			OPForum *pForum = [_delegateBoard.obj_boardStructure getForumFromID: [resultsDict objectForKey: @"forum_id"]];
			OPTopic *cTopic = [[OPTopic alloc] _initWithDataResponse: cTopicDic ofForum: pForum];
			[cPage addObject: [cTopic autorelease]];
		}
	} else {
		for (NSDictionary *cPostDict in [resultsDict objectForKey:@"results"]) {
			OPForum *pForum = [_delegateBoard.obj_boardStructure getForumFromID: [resultsDict objectForKey: @"forum_id"]];
			OPPost *cPost = [[OPPost alloc] _initByLoadingResponsePostObject: cPostDict 
															 fromTopicNumber: [cPostDict objectForKey: @"topic_id"] 
																	 ofForum: pForum];
			[cPage addObject: [cPost autorelease]];
		}
	}
	
	if ([cPage count] > 0)
		[p_results addPage: cPage atIndex: cPageIdx];
	
	[resultsDict release];
}

@end
